"""
文件导出模块
负责将日程数据导出为JSON、CSV、TXT等格式
使用多线程避免界面卡顿
"""
import json
import csv
import os
from datetime import datetime
import threading
import logging
from database import DatabaseManager

class FileExporter:
    def __init__(self, db_manager):
        self.db_manager = db_manager
        self.logger = logging.getLogger(__name__)
        self.export_threads = []
    
    def export_to_json(self, date_str=None, callback=None):
        """导出为JSON格式"""
        def do_export():
            try:
                if date_str is None:
                    date_str = datetime.now().strftime("%Y-%m-%d")
                
                schedules = self.db_manager.get_schedules_by_date(date_str)
                export_data = {
                    "export_time": datetime.now().isoformat(),
                    "export_date": date_str,
                    "schedule_count": len(schedules),
                    "schedules": schedules
                }
                
                # 确保导出目录存在
                os.makedirs('data/exports', exist_ok=True)
                filename = f"schedules_{date_str}_{datetime.now().strftime('%H%M%S')}.json"
                file_path = os.path.join('data/exports', filename)
                
                with open(file_path, 'w', encoding='utf-8') as f:
                    json.dump(export_data, f, ensure_ascii=False, indent=2, default=str)
                
                self.logger.info(f"日程已导出为JSON: {file_path}")
                if callback:
                    callback(True, file_path, f"成功导出 {len(schedules)} 个日程到 JSON")
                    
            except Exception as e:
                self.logger.error(f"导出JSON失败: {e}")
                if callback:
                    callback(False, None, f"导出失败: {str(e)}")
        
        # 在新线程中执行导出
        thread = threading.Thread(target=do_export, name=f"JSONExport_{datetime.now().strftime('%H%M%S')}")
        thread.daemon = True
        thread.start()
        self.export_threads.append(thread)
        return thread
    
    def export_to_csv(self, date_str=None, callback=None):
        """导出为CSV格式"""
        def do_export():
            try:
                if date_str is None:
                    date_str = datetime.now().strftime("%Y-%m-%d")
                
                schedules = self.db_manager.get_schedules_by_date(date_str)
                if not schedules:
                    if callback:
                        callback(False, None, "没有日程数据可导出")
                    return
                
                # 确保导出目录存在
                os.makedirs('data/exports', exist_ok=True)
                filename = f"schedules_{date_str}_{datetime.now().strftime('%H%M%S')}.csv"
                file_path = os.path.join('data/exports', filename)
                
                with open(file_path, 'w', newline='', encoding='utf-8') as f:
                    # 使用第一个日程的键作为列名
                    fieldnames = schedules[0].keys()
                    writer = csv.DictWriter(f, fieldnames=fieldnames)
                    writer.writeheader()
                    writer.writerows(schedules)
                
                self.logger.info(f"日程已导出为CSV: {file_path}")
                if callback:
                    callback(True, file_path, f"成功导出 {len(schedules)} 个日程到 CSV")
                    
            except Exception as e:
                self.logger.error(f"导出CSV失败: {e}")
                if callback:
                    callback(False, None, f"导出失败: {str(e)}")
        
        thread = threading.Thread(target=do_export, name=f"CSVExport_{datetime.now().strftime('%H%M%S')}")
        thread.daemon = True
        thread.start()
        self.export_threads.append(thread)
        return thread
    
    def export_to_text(self, date_str=None, callback=None):
        """导出为可读的文本格式"""
        def do_export():
            try:
                if date_str is None:
                    date_str = datetime.now().strftime("%Y-%m-%d")
                
                schedules = self.db_manager.get_schedules_by_date(date_str)
                
                os.makedirs('data/exports', exist_ok=True)
                filename = f"schedules_{date_str}_{datetime.now().strftime('%H%M%S')}.txt"
                file_path = os.path.join('data/exports', filename)
                
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(f"{'='*60}\n")
                    f.write(f"日程导出报告\n")
                    f.write(f"{'='*60}\n")
                    f.write(f"导出时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
                    f.write(f"导出日期: {date_str}\n")
                    f.write(f"日程数量: {len(schedules)}\n")
                    f.write(f"{'='*60}\n\n")
                    
                    if not schedules:
                        f.write("当天没有日程安排\n")
                    else:
                        for i, schedule in enumerate(schedules, 1):
                            f.write(f"日程 {i}:\n")
                            f.write(f"  📝 标题: {schedule['title']}\n")
                            f.write(f"  ⏰ 时间: {schedule['start_time']}")
                            if schedule['end_time']:
                                f.write(f" - {schedule['end_time']}")
                            f.write("\n")
                            f.write(f"  🎯 优先级: {self._get_priority_text(schedule['priority'])}\n")
                            f.write(f"  📂 类别: {schedule['category']}\n")
                            f.write(f"  📊 状态: {schedule['status']}\n")
                            if schedule['description']:
                                f.write(f"  📄 描述: {schedule['description']}\n")
                            f.write("-" * 40 + "\n\n")
                
                self.logger.info(f"日程已导出为文本: {file_path}")
                if callback:
                    callback(True, file_path, f"成功导出 {len(schedules)} 个日程到文本文件")
                    
            except Exception as e:
                self.logger.error(f"导出文本失败: {e}")
                if callback:
                    callback(False, None, f"导出失败: {str(e)}")
        
        thread = threading.Thread(target=do_export, name=f"TextExport_{datetime.now().strftime('%H%M%S')}")
        thread.daemon = True
        thread.start()
        self.export_threads.append(thread)
        return thread
    
    def export_all_formats(self, date_str=None, callback=None):
        """同时导出所有格式"""
        def do_export():
            try:
                if date_str is None:
                    date_str = datetime.now().strftime("%Y-%m-%d")
                
                results = []
                
                # 导出JSON
                json_thread = self.export_to_json(date_str, 
                    lambda success, path, msg: results.append(("JSON", success, path, msg)))
                json_thread.join()
                
                # 导出CSV
                csv_thread = self.export_to_csv(date_str, 
                    lambda success, path, msg: results.append(("CSV", success, path, msg)))
                csv_thread.join()
                
                # 导出文本
                text_thread = self.export_to_text(date_str, 
                    lambda success, path, msg: results.append(("文本", success, path, msg)))
                text_thread.join()
                
                # 汇总结果
                success_count = sum(1 for _, success, _, _ in results if success)
                total_count = len(results)
                
                if callback:
                    if success_count == total_count:
                        callback(True, None, f"成功导出所有 {total_count} 种格式")
                    else:
                        callback(False, None, f"成功导出 {success_count}/{total_count} 种格式")
                        
            except Exception as e:
                self.logger.error(f"批量导出失败: {e}")
                if callback:
                    callback(False, None, f"批量导出失败: {str(e)}")
        
        thread = threading.Thread(target=do_export, name=f"BatchExport_{datetime.now().strftime('%H%M%S')}")
        thread.daemon = True
        thread.start()
        self.export_threads.append(thread)
        return thread
    
    def _get_priority_text(self, priority):
        """将优先级数字转换为文本"""
        priority_map = {1: "低", 2: "中", 3: "高"}
        return priority_map.get(priority, "未知")
    
    def get_export_files(self):
        """获取所有导出文件列表"""
        export_dir = 'data/exports'
        if not os.path.exists(export_dir):
            return []
        
        files = []
        for filename in os.listdir(export_dir):
            file_path = os.path.join(export_dir, filename)
            if os.path.isfile(file_path):
                stat = os.stat(file_path)
                files.append({
                    'name': filename,
                    'path': file_path,
                    'size': stat.st_size,
                    'modified': datetime.fromtimestamp(stat.st_mtime),
                    'type': os.path.splitext(filename)[1].upper().replace('.', '')
                })
        
        # 按修改时间倒序排列
        files.sort(key=lambda x: x['modified'], reverse=True)
        return files
    
    def cleanup_old_exports(self, keep_count=20):
        """清理旧的导出文件，只保留指定数量的最新文件"""
        try:
            files = self.get_export_files()
            if len(files) <= keep_count:
                return 0
            
            # 删除超出数量的旧文件
            deleted_count = 0
            for file_info in files[keep_count:]:
                try:
                    os.remove(file_info['path'])
                    self.logger.info(f"删除旧导出文件: {file_info['name']}")
                    deleted_count += 1
                except Exception as e:
                    self.logger.error(f"删除文件失败 {file_info['name']}: {e}")
            
            self.logger.info(f"清理完成，删除了 {deleted_count} 个旧导出文件")
            return deleted_count
            
        except Exception as e:
            self.logger.error(f"清理旧导出文件失败: {e}")
            return 0

    # 在 FileExporter 类中添加线程安全机制
    def __init__(self, db_manager):
        self.db_manager = db_manager
        self.logger = logging.getLogger(__name__)
        self.export_threads = []
        self.export_lock = threading.Lock()  # 添加线程锁

    def export_to_json(self, date_str=None, callback=None):
        """导出为JSON格式"""
        def do_export():
            try:
                # 使用线程锁确保文件操作安全
                with self.export_lock:
                    if date_str is None:
                        date_str = datetime.now().strftime("%Y-%m-%d")
                    
                    schedules = self.db_manager.get_schedules_by_date(date_str)
                    export_data = {
                        "export_time": datetime.now().isoformat(),
                        "export_date": date_str,
                        "schedule_count": len(schedules),
                        "schedules": schedules
                    }
                    
                    # 确保导出目录存在
                    os.makedirs('data/exports', exist_ok=True)
                    filename = f"schedules_{date_str}_{datetime.now().strftime('%H%M%S')}.json"
                    file_path = os.path.join('data/exports', filename)
                    
                    with open(file_path, 'w', encoding='utf-8') as f:
                        json.dump(export_data, f, ensure_ascii=False, indent=2, default=str)
                    
                    self.logger.info(f"日程已导出为JSON: {file_path}")
                    if callback:
                        callback(True, file_path, f"成功导出 {len(schedules)} 个日程到 JSON")
                        
            except Exception as e:
                self.logger.error(f"导出JSON失败: {e}")
                if callback:
                    callback(False, None, f"导出失败: {str(e)}")
        
        # 在新线程中执行导出
        thread = threading.Thread(target=do_export, name=f"JSONExport_{datetime.now().strftime('%H%M%S')}")
        thread.daemon = True
        thread.start()
        self.export_threads.append(thread)
        return thread


# 测试函数
def test_file_export():
    """测试文件导出功能"""
    import tempfile
    
    # 使用临时数据库测试
    temp_db = tempfile.NamedTemporaryFile(delete=False, suffix='.db')
    temp_db.close()
    
    try:
        from database import DatabaseManager
        
        # 初始化数据库
        db = DatabaseManager(temp_db.name)
        
        # 添加测试数据
        db.add_schedule("测试日程1", "2024-01-01 10:00:00", "描述1")
        db.add_schedule("测试日程2", "2024-01-01 14:00:00", "描述2")
        
        # 创建导出器
        exporter = FileExporter(db)
        
        # 测试JSON导出
        def json_callback(success, path, msg):
            print(f"JSON导出: {success}, {msg}")
            if success and path:
                print(f"文件路径: {path}")
        
        exporter.export_to_json("2024-01-01", json_callback)
        
        # 等待导出完成
        import time
        time.sleep(2)
        
        # 测试获取导出文件列表
        files = exporter.get_export_files()
        print(f"找到 {len(files)} 个导出文件")
        
        print("文件导出测试完成!")
        
    except Exception as e:
        print(f"文件导出测试失败: {e}")
    finally:
        # 清理临时文件
        if os.path.exists(temp_db.name):
            os.unlink(temp_db.name)

if __name__ == "__main__":
    # 配置日志
    logging.basicConfig(level=logging.INFO)
    
    # 测试文件导出
    test_file_export()